(*$U-*)
PROGRAM PASCALSYSTEM;

(************************************************)
(*                                              *)
(*    UCSD PASCAL OPERATING SYSTEM              *)
(*                                              *)
(*    RELEASE LEVEL:  I.3   AUGUST, 1977        *)
(*                                              *)
(*    WRITTEN BY ROGER T. SUMNER                *)
(*    WINTER 1977                               *)
(*                                              *)
(*    INSTITUTE FOR INFORMATION SYSTEMS         *)
(*    UC SAN DIEGO, LA JOLLA, CA                *)
(*                                              *)
(*    KENNETH L. BOWLES, DIRECTOR               *)
(*                                              *)
(*    THIS SOFTWARE IS THE PROPERTY OF THE      *)
(*  REGENTS OF THE UNIVERSITY OF CALIFORNIA.    *)
(*                                              *)
(************************************************)

CONST
     MAXUNIT = 8;	(*MAXIMUM PHYSICAL UNIT # FOR UREAD*)
     MAXDIR = 77;	(*MAX NUMBER OF ENTRIES IN A DIRECTORY*)
     VIDLENG = 7;	(*NUMBER OF CHARS IN A VOLUME ID*)
     TIDLENG = 15;	(*NUMBER OF CHARS IN TITLE ID*)
     MAXSEG = 15;	(*MAX CODE SEGMENT NUMBER*)
     FBLKSIZE = 512;	(*STANDARD DISK BLOCK LENGTH*)
     DIRBLK = 2;	(*DISK ADDR OF DIRECTORY*)
     AGELIMIT = 300;	(*MAX AGE FOR GDIRP...IN TICKS*)
     EOL = 13;		(*END-OF-LINE...ASCII CR*)

TYPE

     IORSLTWD = (INOERROR,IBADBLOCK,IBADUNIT,IBADMODE,IHARDXTRA,
		 ILOSTUNIT,ILOSTFILE,IBADTITLE,INOROOM,INOUNIT,
		 INOFILE,IDUPFILE,INOTCLOSED,INOTOPEN,IBADFORMAT);

					(*ARCHIVAL INFO...THE DATE*)

     DATEREC = PACKED RECORD
		 MONTH: 0..12;		(*0 IMPLIES DATE NOT MEANINGFUL*)
		 DAY: 0..31;		(*DAY OF MONTH*)
		 YEAR: 0..100		(*100 IS TEMP DISK FLAG*)
	       END (*DATEREC*) ;

					(*VOLUME TABLES*)
     UNITNUM = 0..MAXUNIT;
     VID = STRING[VIDLENG];

					(*DISK DIRECTORIES*)
     DIRRANGE = 0..MAXDIR;
     TID = STRING[TIDLENG];

     FILEKIND = (UNTYPEDFILE,XDSKFILE,CODEFILE,TEXTFILE,
		 INFOFILE,DATAFILE,GRAFFILE,FOTOFILE);

     DIRENTRY = RECORD
		  DFIRSTBLK: INTEGER;	(*FIRST PHYSICAL DISK ADDR*)
		  DLASTBLK: INTEGER;	(*POINTS AT BLOCK FOLLOWING*)
		  CASE DFKIND: FILEKIND OF
		    UNTYPEDFILE: (*ONLY IN DIR[0]...VOLUME INFO*)
		       (DVID: VID;		(*NAME OF DISK VOLUME*)
			DEOVBLK: INTEGER;	(*LASTBLK OF VOLUME*)
			DNUMFILES: DIRRANGE;	(*NUM FILES IN DIR*)
			DLOADTIME: INTEGER);	(*TIME OF LAST ACCESS*)
		    XDSKFILE,CODEFILE,TEXTFILE,INFOFILE,
		    DATAFILE,GRAFFILE,FOTOFILE:
		       (DTID: TID;		(*TITLE OF FILE*)
			DLASTBYTE: 1..FBLKSIZE;	(*NUM BYTES IN LAST BLOCK*)
			DACCESS: DATEREC)	(*LAST MODIFICATION DATE*)
		END (*DIRENTRY*) ;

     DIRP = ^DIRECTORY;

     DIRECTORY = ARRAY [DIRRANGE] OF DIRENTRY;

					(*FILE INFORMATION*)

     CLOSETYPE = (CNORMAL,CLOCK,CPURGE,CCRUNCH);
     WINDOWP = ^WINDOW;
     WINDOW = PACKED ARRAY [0..0] OF CHAR;
     FIBP = ^FIB;

     FIB = RECORD
	     FWINDOW: WINDOWP;	(*USER WINDOW...F^, USED BY GET-PUT*)
	     FEOF,FEOLN: BOOLEAN;
	     FRECSIZE: INTEGER;	(*IN BYTES...0=>BLOCKFILE, 1=>CHARFILE*)
	     CASE FISOPEN: BOOLEAN OF
	       TRUE: (FISBLKD,		(*FILE IS ON BLOCK DEVICE*)
		      FGOTACHAR:BOOLEAN;(*MARK FOR CHAR LOOK-AHEAD*)
		      FUNIT: UNITNUM;	(*PHYSICAL UNIT #*)
		      FVID: VID;	(*VOLUME NAME*)
		      FNXTBLK,		(*NEXT REL BLOCK TO IO*)
		      FMAXBLK: INTEGER;	(*MAX REL BLOCK ACCESSED*)
		      FMODIFIED:BOOLEAN;(*PLEASE SET NEW DATE IN CLOSE*)
		      FHEADER: DIRENTRY;(*COPY OF DISK DIR ENTRY*)
		      CASE FSOFTBUF: BOOLEAN OF	(*DISK GET-PUT STUFF*)
			TRUE: (FNXTBYTE,FMAXBYTE: INTEGER;
			       FBUFCHNGD: BOOLEAN;
			       FBUFFER: PACKED ARRAY [0..FBLKSIZE] OF CHAR))
	   END (*FIB*) ;

					(*USER WORKFILE STUFF*)

     INFOREC = RECORD
		 SYMFIBP,CODEFIBP: FIBP;	(*WORKFILES FOR SCRATCH*)
		 ERRSYM,ERRBLK,ERRNUM: INTEGER;	(*ERROR STUFF IN EDIT*)
		 STUPID: BOOLEAN;		(*STUDENT PROGRAMMER ID!!*)
		 GOTSYM,GOTCODE: BOOLEAN;	(*TITLES ARE MEANINGFUL*)
		 WORKVID,SYMVID,CODEVID: VID;	(*PERM&CUR WORKFILE VOLUMES*)
		 WORKTID,SYMTID,CODETID: TID	(*PERM&CUR WORKFILES TITLE*)
	       END (*INFOREC*) ;

					(*CODE SEGMENT LAYOUTS*)

     SEGRANGE = 0..MAXSEG;
     SEGDESC = RECORD
		 DISKADDR: INTEGER;	(*REL # IN CODE...ABS # IN SYSCOM^*)
		 CODELENG: INTEGER	(*# BYTES TO READ IN*)
	       END (*SEGDESC*) ;

					(*DEBUGGER STUFF*)

     BYTERANGE = 0..255;
     TRICKARRAY = ARRAY [0..0] OF INTEGER; (* FOR MEMORY DIDDLING*)
     MSCWP = ^ MSCW;		(*MARK STACK RECORD POINTER*)
     MSCW = RECORD
	      STATLINK: MSCWP;	(*POINTER TO PARENT MSCW*)
	      DYNLINK: MSCWP;	(*POINTER TO CALLER'S MSCW*)
	      MSSEG,MSJTAB: ^TRICKARRAY;
	      MSIPC: INTEGER;
	      LOCALDATA: TRICKARRAY
	    END (*MSCW*) ;

					(*SYSTEM COMMUNICATION AREA*)
					(*SEE INTERPRETERS...NOTE  *)
					(*THAT WE ASSUME BACKWARD  *)
					(*FIELD ALLOCATION IS DONE *)
     SYSCOMREC = RECORD
		   IORSLT: IORSLTWD;	(*RESULT OF LAST IO CALL*)
		   XEQERR: INTEGER;	(*REASON FOR EXECERROR CALL*)
		   SYSUNIT: UNITNUM;	(*PHYSICAL UNIT OF BOOTLOAD*)
		   BUGSTATE: INTEGER;(*DEBUGGER INFO*)
		   GDIRP: DIRP;		(*GLOBAL DIR POINTER,SEE VOLSEARCH*)
		   LASTMP,STKBASE,BOMBP: MSCWP;
		   MEMTOP,SEG,JTAB: INTEGER;
		   BOMBIPC: INTEGER;	(*WHERE XEQERR BLOWUP WAS*)
		   EXPANSION: ARRAY [0..14] OF INTEGER;
		   HIGHTIME,LOWTIME: INTEGER;
		   MISCINFO: PACKED RECORD
			       NOBREAK,STUPID,SLOWTERM,
			       HASXYCRT,HASLCCRT,HAS8510A,HASCLOCK: BOOLEAN
			     END;
		   CRTTYPE: INTEGER;
		   CRTCTRL: PACKED RECORD
			      RLF,NDFS,ERASEEOL,ERASEEOS,HOME,ESCAPE: CHAR;
			      BACKSPACE: CHAR;
			      FILLCOUNT: 0..255;
			      EXPANSION: PACKED ARRAY [0..3] OF CHAR
			    END;
		   CRTINFO: PACKED RECORD
			      WIDTH,HEIGHT: INTEGER;
			      RIGHT,LEFT,DOWN,UP: CHAR;
			      BADCH,CHARDEL,STOP,BREAK,FLUSH,EOF: CHAR;
			      ALTMODE,LINEDEL: CHAR;
			      EXPANSION: PACKED ARRAY [0..5] OF CHAR
			    END;
		   SEGTABLE: ARRAY [SEGRANGE] OF
			       RECORD
				 CODEUNIT: UNITNUM;
				 CODEDESC: SEGDESC
			       END
		 END (*SYSCOM*);

VAR
    SYSCOM: ^SYSCOMREC;			(*MAGIC PARAM...SET UP IN BOOT*)
    GFILES: ARRAY [0..5] OF FIBP;	(*GLOBAL FILES, 0=INPUT, 1=OUTPUT*)
    EMPTYHEAP: ^INTEGER;		(*HEAP MARK FOR MEM MANAGING*)
    INPUTFIB,OUTPUTFIB,SYSTERM: FIBP;	(*ACTUAL FILES...GFILES ARE COPIES*)
    SYVID,DKVID: VID;			(*SYSUNIT VOLID & DEFAULT VOLID*)
    THEDATE: DATEREC;			(*TODAY...SET IN FILER OR SIGN ON*)
    DEBUGINFO: ^INTEGER;		(*DEBUGGERS GLOBAL INFO WHILE RUNIN*)
    PL: STRING;				(*PROMPTLINE STRING...SEE PROMPT*)
    IPOT: ARRAY [0..4] OF INTEGER;	(*INTEGER POWERS OF TEN*)
    FILLER: STRING[11];			(*NULLS FOR CARRIAGE DELAY*)
    USERINFO: INFOREC;			(*WORK STUFF FOR COMPILER ETC*)
    UNITABLE: ARRAY [UNITNUM] OF (*0 NOT USED*)
		RECORD
		  UVID: VID;	(*VOLUME ID FOR UNIT*)
		  CASE UISBLKD: BOOLEAN OF
		    TRUE: (UEOVBLK: INTEGER)
		END (*UNITABLE*) ;

(*-------------------------------------------------------------------------*)
(* SYSTEM PROCEDURE FORWARD DECLARATIONS *)
(* THESE ARE ADDRESSED BY OBJECT CODE... *)
(*  DO NOT MOVE WITHOUT CAREFUL THOUGHT  *)

PROCEDURE EXECERROR;
  FORWARD;
PROCEDURE FINIT(VAR F: FIB; WINDOW: WINDOWP; RECWORDS: INTEGER);
  FORWARD;
PROCEDURE FRESET(VAR F: FIB);
  FORWARD;
PROCEDURE FOPEN(VAR F: FIB; VAR FTITLE: STRING;
		FOPENOLD: BOOLEAN; JUNK: FIBP);
  FORWARD;
PROCEDURE FCLOSE(VAR F: FIB; FTYPE: CLOSETYPE);
  FORWARD;
PROCEDURE FGET(VAR F: FIB);
  FORWARD;
PROCEDURE FPUT(VAR F: FIB);
  FORWARD;
PROCEDURE FSEEK(VAR F: FIB);
  FORWARD;
FUNCTION FEOF(VAR F: FIB): BOOLEAN;
  FORWARD;
FUNCTION FEOLN(VAR F: FIB): BOOLEAN;
  FORWARD;
PROCEDURE FREADINT(VAR F: FIB; VAR I: INTEGER);
  FORWARD;
PROCEDURE FWRITEINT(VAR F: FIB; I,RLENG: INTEGER);
  FORWARD;
PROCEDURE FREADREAL(VAR F: FIB; VAR X: REAL);
  FORWARD;
PROCEDURE FWRITEREAL(VAR F: FIB; X: REAL; W,D: INTEGER);
  FORWARD;
PROCEDURE FREADCHAR(VAR F: FIB; VAR CH: CHAR);
  FORWARD;
PROCEDURE FWRITECHAR(VAR F: FIB; CH: CHAR; RLENG: INTEGER);
  FORWARD;
PROCEDURE FREADSTRING(VAR F: FIB; VAR S: STRING; SLENG: INTEGER);
  FORWARD;
PROCEDURE FWRITESTRING(VAR F: FIB; VAR S: STRING; RLENG: INTEGER);
  FORWARD;
PROCEDURE FWRITEBYTES(VAR F: FIB; VAR A: WINDOW; RLENG,ALENG: INTEGER);
  FORWARD;
PROCEDURE FREADLN(VAR F: FIB);
  FORWARD;
PROCEDURE FWRITELN(VAR F: FIB);
  FORWARD;
PROCEDURE SCONCAT(VAR DEST,SRC: STRING; DESTLENG: INTEGER);
  FORWARD;
PROCEDURE SINSERT(VAR SRC,DEST: STRING; DESTLENG,INSINX: INTEGER);
  FORWARD;
PROCEDURE SCOPY(VAR SRC,DEST: STRING; SRCINX,COPYLENG: INTEGER);
  FORWARD;
PROCEDURE SDELETE(VAR DEST: STRING; DELINX,DELLENG: INTEGER);
  FORWARD;
FUNCTION SPOS(VAR TARGET,SRC: STRING): INTEGER;
  FORWARD;
FUNCTION FBLOCKIO(VAR F: FIB; VAR A: WINDOW;
		  NBLOCKS,RBLOCK: INTEGER; DOREAD: BOOLEAN): INTEGER;
  FORWARD;

(* NON FIXED FORWARD DECLARATIONS *)

FUNCTION VOLSEARCH(VAR FVID: VID; LOOKHARD: BOOLEAN;
		   VAR FDIR: DIRP): UNITNUM;
  FORWARD;
PROCEDURE WRITEDIR(FUNIT: UNITNUM; FDIR: DIRP);
  FORWARD;
FUNCTION DIRSEARCH(VAR FTID: TID; FINDPERM: BOOLEAN; FDIR: DIRP): DIRRANGE;
  FORWARD;
FUNCTION SCANTITLE(FTITLE: STRING; VAR FVID: VID; VAR FTID: TID;
		   VAR FSEGS: INTEGER; VAR FKIND: FILEKIND): BOOLEAN;
  FORWARD;
PROCEDURE DELENTRY(FINX: DIRRANGE; FDIR: DIRP);
  FORWARD;
PROCEDURE INSENTRY(VAR FENTRY: DIRENTRY; FINX: DIRRANGE; FDIR: DIRP);
  FORWARD;
PROCEDURE CLEARSCREEN;
  FORWARD;
PROCEDURE PROMPT;
  FORWARD;
FUNCTION SPACEWAIT: BOOLEAN;
  FORWARD;
FUNCTION GETCHAR(FLUSH: BOOLEAN): CHAR;
  FORWARD;
PROCEDURE EXECUTE(RUNWORKFILE: BOOLEAN);
  FORWARD;
PROCEDURE COMMAND;
  FORWARD;
